home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 007 / jovept2.arc / MAIN.C < prev    next >
Encoding:
C/C++ Source or Header  |  1985-05-30  |  10.8 KB  |  721 lines

  1. /* jove_main.c */
  2.  
  3. /*
  4.    Jonathan Payne at Lincoln-Sudbury Regional High School 4-19-83
  5.  
  6.    jove_main.c
  7.  
  8.    Contains the main loop, initializations, getch routine... */
  9.  
  10.  
  11. #include "jove.h"
  12.  
  13. #ifdef UNIX
  14. #include <sys/ioctl.h>
  15. #include <signal.h>
  16. #include <sgtty.h>
  17. #else
  18. #include "signal.h"
  19. #endif
  20.  
  21. #ifdef BUGS
  22. extern char *stdout;
  23. #endif
  24.  
  25.  
  26. extern int EscPrefix();
  27. extern int CtlxPrefix();
  28. extern int Forget();
  29. extern int    errormsg;
  30. extern int OKXonXoff;    /* funcs.h */
  31. extern FMACRO *macstack[NMACROS];    /* funcs.h */
  32. extern FMACRO KeyMacro;    /* funcs.h */
  33. extern int stackp;    /* funcs.h */
  34. extern char    *tfname;
  35.  
  36.  
  37. #define NTOBUF    20        /* Should never get that far ahead */
  38.  
  39. /* globals */
  40.  
  41.  
  42. int (*Gtchar)();
  43.  
  44. int
  45.     tabstop,
  46.     LastKeyStruck,
  47.     UpdMesg,
  48.     BufSize,
  49.     peekc,
  50.     io,                    /* file desc. */
  51.     exp,
  52.     exp_p,
  53.     this_cmd,
  54.     last_cmd,    
  55.     Input,                /* char that is waiting */
  56.     InputPending,        /* 0 if no char waiting */
  57.     killptr,
  58.     CanScroll,
  59.     Asking,                /* 1 if inputting string */
  60.     globflags[NFLAGS];
  61.  
  62. char
  63.     **argvp,
  64.     mesgbuf[100],
  65.     linebuf[LBSIZE],
  66.     genbuf[LBSIZE];
  67.  
  68. LINE
  69.     *killbuf[NUMKILLS];    /* Array of pointers to killed stuff */
  70.  
  71. WINDOW
  72.     *fwind,                /* first window in list */
  73.     *curwind;            /* current window */
  74.  
  75.  
  76. BUFFER
  77.     *curbuf;        /* Pointer into world for current buffer */
  78.  
  79. FUNCT
  80.     *mainmap[0200],
  81.     *pref1map[0200],
  82.     *pref2map[0200],
  83.     *LastFunc;
  84.  
  85. #ifndef UNIX
  86. FUNC eprefix;
  87. FUNC cprefix;
  88. FUNC frgt;
  89. #endif
  90.  
  91. #ifdef UNIX
  92. extern IOBUF
  93.     termout;
  94. #endif
  95.  
  96. /* o.s. dependent var. */
  97.  
  98. #ifdef UNIX
  99. #ifdef TIOCSLTC
  100. struct ltchars    ls1,
  101.         ls2;
  102. #endif
  103. struct tchars    tc1,
  104.         tc2;
  105. #endif
  106.  
  107. /* non-global but shared */
  108.  
  109. int    errormsg, Crashing;
  110. int origflags[NFLAGS];
  111. char *Mainbuf = "Main";
  112. BUFFER    *world;            /* First buffer */
  113. jmp_buf    mainjmp;
  114.  
  115. /* static var */
  116.  
  117. static char    smbuf[NTOBUF],
  118.         *bp = smbuf;
  119. static int    nchars = 0;
  120.  
  121. static int iniargc;
  122. static char **iniargv;
  123.  
  124.  
  125.  
  126. finish(code)
  127. {
  128.     char    c;
  129.     int    Crashit = code && (code != LOGOEXIT);
  130.  
  131.     if (code == SIGINT) {
  132.  
  133.  
  134. #ifdef UNIX
  135. #ifndef SIGTSTP            /* Job stopping in other words */
  136.         ignorf(signal(code, finish));
  137. #endif
  138. #endif
  139.         message("Quit? ");
  140.         UpdateMesg();
  141.         ignore(read(0, &c, 1));
  142.         message("");
  143.         if ((c & 0377) != 'y') {
  144.             redisplay();
  145.             return;
  146.         }
  147.     }
  148.     if (Crashit) {
  149.         if (!Crashing) {
  150.             putstr("Writing modified JOVE buffers...");
  151.             Crashing++;
  152.             exp_p = 0;
  153.             WtModBuf();
  154.         } else
  155.             putstr("Complete lossage!");
  156.     }
  157.     ttyset(0);
  158. #ifdef UNIX
  159.     term_exit();
  160. #else
  161.     closetmp();
  162. #endif
  163.     ignore(unlink(tfname));
  164.     if (Crashit)
  165.         abort();
  166. #ifndef UNIX
  167.     cleanup();
  168.     exit(0);
  169. #else
  170.     exit(code);
  171. #endif
  172. }
  173.  
  174.  
  175. Ungetc(c)
  176. int    c;
  177. {
  178.     if (c == EOF || nchars >= NTOBUF)
  179.         return EOF;
  180.     *--bp = c;
  181.     nchars++;
  182.     return c;
  183. }
  184.  
  185. getchar()
  186. {
  187.     if (nchars == 0) {
  188. #ifdef UNIX
  189.         if ((nchars = read(Input, smbuf, sizeof smbuf)) == 0) {
  190. #else
  191.         if ((nchars = conread(Input, smbuf, sizeof smbuf)) == 0) {
  192. #endif
  193.             if (Input)
  194.                 return EOF;
  195.             finish(0);
  196.         }
  197.         bp = smbuf;
  198.         InputPending = nchars > 1;
  199.     }
  200.     nchars--;
  201.     return *bp++;
  202. }
  203.  
  204. PauseJove()
  205. {
  206. #ifdef UNIX
  207.     UnsetTerm();
  208. #endif
  209.  
  210. #ifdef SIGTSTP
  211.     ignore(kill(0, SIGTSTP));
  212. #else
  213.     Suspend();
  214. #endif
  215. #ifdef UNIX
  216.     ResetTerm();
  217. #endif
  218.     ClAndRedraw();
  219. }
  220.  
  221.  
  222.  
  223.  
  224. ReInitTTY()
  225. {
  226.     ttyset(0);    /* Back to original settings */
  227.     ttinit();
  228. }
  229.  
  230.  
  231. /* NOSTRICT */
  232.  
  233. char *
  234. emalloc(size)
  235. {
  236.     char    *ptr;
  237.  
  238.     if (ptr = malloc((unsigned) size)) {
  239.  
  240. #ifndef UNIX
  241.         setmem(ptr,(unsigned) size,0);
  242. #endif
  243.         return ptr;
  244.     }
  245.     GCchunks();
  246.     if (ptr = malloc((unsigned) size)) {
  247. #ifndef UNIX
  248.         setmem(ptr,(unsigned) size,0);
  249. #endif
  250.         return ptr;
  251.     }
  252.     error("out of memory");
  253.     /* NOTREACHED */
  254. }
  255.  
  256. dispatch(c)
  257. register int    c;
  258. {
  259.     FUNCT *fp;
  260.  
  261.     fp = mainmap[c];
  262.     if (fp == 0) {
  263.         rbell();
  264.         exp = 1;
  265.         exp_p = errormsg = 0;
  266.         message("");
  267.         return;
  268.     }
  269.     ExecFunc(fp, 0);
  270. }
  271.  
  272. getch()
  273. {
  274.     int    c;
  275.  
  276.     if (stackp >= 0 && macstack[stackp]->Flags & EXECUTE)
  277.         c = MacGetc();
  278.     else {
  279.          redisplay();
  280.         if ((c = getchar()) == EOF)
  281.             finish(SIGHUP);
  282.         c &= 0177;
  283.         if (KeyMacro.Flags & DEFINE)
  284.             MacPutc(c);
  285.     }
  286.     LastKeyStruck = c;
  287.     return c;
  288. }
  289.  
  290. parse(argc, argv)
  291. char    *argv[];
  292. {
  293.     BUFFER    *firstbuf = 0;
  294.     char    c;
  295.  
  296.     message("Jonathan's Own Version of Emacs");
  297.  
  298.     *argv = (char *) 0;
  299.     argvp = argv + 1;
  300.  
  301.     while (argc > 1) {
  302.         if (argv[1][0] == '-') {
  303.             if (argv[1][1] == 't') {
  304.                 ++argv;
  305.                 --argc;
  306.                 exp_p = 1;
  307.                 find_tag(argv[1]);
  308.                 if (!firstbuf)
  309.                     firstbuf = curbuf;
  310.             }
  311.         } else if (argv[1][0] == '+' &&
  312.                     (c = argv[1][1]) >= '0' && c <= '9') {
  313.             ++argv;
  314.             --argc;
  315.             SetBuf(do_find(curwind, argv[1]));
  316.             if (!firstbuf)
  317.                 firstbuf = curbuf;
  318.             SetLine(next_line(curline, atoi(&argv[0][1]) - 1));
  319.         } else {
  320.             SetBuf(do_find(curwind, argv[1]));
  321.             if (!firstbuf)
  322.                 firstbuf = curbuf;
  323.         }
  324.  
  325.         ++argv;
  326.         --argc;
  327.     }
  328.  
  329.     if (firstbuf)
  330.         SetBuf(firstbuf);
  331. }
  332.  
  333. copy_n(f, t, n)
  334. register int    *f,
  335.         *t,
  336.         n;
  337. {
  338.     while (n--)
  339.         *f++ = *t++;
  340. }
  341.  
  342. #ifdef lint
  343. Ignore(a)
  344.     char *a;
  345. {
  346.  
  347.     a = a;
  348. }
  349.  
  350. Ignorf(a)
  351.     int (*a)();
  352. {
  353.  
  354.     a = a;
  355. }
  356. #endif
  357.  
  358. /* VARARGS1 */
  359.  
  360. error(fmt, args)
  361. char    *fmt;
  362. {
  363.     if (fmt) {
  364.         format(mesgbuf, fmt, &args);
  365.         UpdMesg++;
  366.     }
  367.     rbell();
  368.     longjmp(mainjmp, ERROR);
  369. }
  370.  
  371. /* VARARGS1 */
  372.  
  373. complain(fmt, args)
  374. char    *fmt;
  375. {
  376.     if (fmt) {
  377.         format(mesgbuf, fmt, &args);
  378.         UpdMesg++;
  379.     }
  380.     rbell();    /* Always ring the bell now */
  381.     longjmp(mainjmp, COMPLAIN);
  382. }
  383.  
  384. /* VARARGS1 */
  385.  
  386. confirm(fmt, args)
  387. char    *fmt;
  388. {
  389.     char *yorn;
  390.     char *def;
  391.     def = "\0";
  392.  
  393.     format(mesgbuf, fmt, &args);
  394.     yorn = ask(def, mesgbuf);
  395.     if (*yorn != 'Y' && *yorn != 'y')
  396.         longjmp(mainjmp, COMPLAIN);
  397.     return;
  398. }
  399.  
  400. read_ch()
  401. {
  402.     int    c;
  403.     if ((c = peekc) != -1) {
  404.         peekc = -1;
  405.         return c;
  406.     }
  407.     return getch();
  408. }
  409.  
  410. DoKeys(first)
  411. {
  412.     int    c;
  413.     jmp_buf    savejmp;
  414.     int code;
  415.  
  416.     copynchar((char *) savejmp, (char *) mainjmp, sizeof savejmp);
  417.  
  418.     code = setjmp(mainjmp);
  419.     switch (code) {
  420.     case 0:
  421.         if (first)
  422.             parse(iniargc, iniargv);
  423.         break;
  424.  
  425.     case QUIT:
  426.         copynchar((char *) mainjmp, (char *) savejmp, sizeof mainjmp);
  427.  
  428.         return;
  429.  
  430.     case ERROR:
  431.         getDOT();    /* God knows what state linebuf was in */
  432.  
  433.     case COMPLAIN:
  434.         IOclose();
  435.         Gtchar = getch;
  436.         if (Input) {
  437.             ignore(close(Input));
  438.             Input = 0;    /* Terminal has control now */
  439.         }
  440.         errormsg++;
  441.         FixMacros();
  442.         Asking = 0;        /* Not anymore we ain't */
  443.         redisplay();
  444.         break;
  445.     }
  446.  
  447.     this_cmd = last_cmd = 0;
  448.  
  449.     for (;;) {
  450.         exp = 1;
  451.         exp_p = 0;
  452.         last_cmd = this_cmd;
  453. cont:
  454.         this_cmd = 0;
  455.         c = read_ch();
  456.          if(errormsg) {
  457.              message("");
  458.              errormsg = 0;
  459.              redisplay();
  460.          }
  461.  
  462.         if (c == -1)
  463.             continue;
  464.          dispatch(c);
  465.         if (this_cmd == ARG_CMD)
  466.             goto cont;
  467.     }
  468. }
  469.  
  470.  
  471.  
  472. main(argc, argv)
  473. char    *argv[];
  474. {
  475.     extern char searchbuf[];
  476.     char    *home;
  477.  
  478. #ifndef UNIX
  479.     eprefix = &EscPrefix;
  480.     cprefix = &CtlxPrefix;
  481.     frgt = &Forget;
  482. #endif    
  483.  
  484.     tabstop = 4;
  485.     peekc = -1;
  486.     killptr = errormsg = 0;
  487.     curbuf = world = (BUFFER *) 0;
  488.  
  489.     iniargc = argc;
  490.     iniargv = argv;
  491.  
  492.     searchbuf[0] = '\0';
  493.     InputPending = 0;
  494.     Asking = 0;
  495.     Crashing = 0;
  496.     Input = 0;        /* Terminal? */
  497.  
  498.     Gtchar = getch;
  499.  
  500.     if (setjmp(mainjmp)) {
  501.         printf("Pre-error: \"%s\"; tell Jon Payne\n", mesgbuf);
  502.         finish(0);
  503.     }
  504.  
  505.     getTERM(0);
  506.     InitCM();
  507.     settout();
  508.     make_scr();    /* Do this before making zero */
  509.     tmpinit();    /* Init temp file */
  510.     MacInit();    /* Initialize Macros */
  511.     InitFuncs();    /* Initialize functions and variables */
  512.     InitBindings();    /* Everyday EMACS commands */
  513.     winit();    /* Initialize window */
  514.     noflags(origflags);
  515.     curbuf = do_select(curwind, Mainbuf);
  516.  
  517. #ifdef UNIX
  518.     if (home = getenv("HOME"))
  519.         ignore(joverc(sprint("%s/.joverc", home)));
  520. #endif
  521.     ttinit();    /* Initialize terminal (after ~/.joverc) */
  522. #ifdef UNIX
  523.     init_term();
  524. #endif
  525.     copy_n(origflags, curbuf->b_flags, NFLAGS);
  526.     /* All new buffers will have these flags when created. */
  527.     RedrawDisplay();    /* Start the redisplay process */
  528.     DoKeys(1);
  529.     finish(0);
  530. }
  531.  
  532. Beep()
  533. {
  534.     message("");
  535.     rbell();        /* Ring the bell (or flash) */
  536.     errormsg = 0;
  537. }
  538.  
  539. /*-------------------o.s. dependent----------------------------------------*/
  540.  
  541.  
  542. #ifdef UNIX
  543.  
  544. /* Returns non-zero if a character waiting */
  545.  
  546. charp()
  547. {
  548.     if (Input)
  549.         return 0;
  550.     if (nchars)        /* Quick check */
  551.         return 1;
  552.  
  553.     else {
  554. #ifdef FIONREAD
  555.         long    c;
  556.  
  557.         if (ioctl(0, FIONREAD, (char *) &c) == -1)
  558. #else
  559.         int    c;
  560.  
  561.         if (ioctl(0, TIOCEMPTY, (char *) &c) == -1)
  562. #endif
  563.             c = 0;
  564.         return (c > 0);
  565.     }
  566. }
  567.  
  568.  
  569.  
  570. #ifndef SIGTSTP
  571. Suspend()
  572. {
  573.     char    *shell,
  574.         *getenv();
  575.     int    pid;
  576.  
  577.     switch (pid = fork()) {
  578.     case -1:
  579.         complain("Fork failed");
  580.  
  581.     case 0:
  582.         signal(SIGTERM, SIG_DFL);
  583.         signal(SIGINT, SIG_DFL);
  584.         execl(shell ? shell : "/bin/csh", "ed_shell", 0);
  585.         message("Execl failed");
  586.         _exit(1);
  587.  
  588.     default:
  589.         signal(SIGQUIT, SIG_IGN);
  590.         while (wait(0) != pid)
  591.             ;
  592.         signal(SIGQUIT, finish);
  593.     }
  594. }
  595. #endif
  596.  
  597. ttinit()
  598. {
  599. #ifdef TIOCSLTC
  600.     ioctl(0, TIOCGLTC, (char *) &ls1);
  601.     ls2 = ls1;
  602.     ls2.t_suspc = (char) -1;
  603.     ls2.t_dsuspc = (char) -1;
  604.     ls2.t_rprntc = (char) -1;
  605.     ls2.t_flushc = (char) -1;
  606.     ls2.t_werasc = (char) -1;
  607.     ls2.t_lnextc = (char) -1;    
  608.  
  609. #endif
  610.  
  611.     /* Change interupt and quit. */
  612.     ioctl(0, TIOCGETC, (char *) &tc1);
  613.     tc2 = tc1;
  614.     tc2.t_intrc = '\035';
  615.     tc2.t_quitc = (char) -1;
  616.     if (OKXonXoff) {
  617.         tc2.t_stopc = (char) -1;
  618.         tc2.t_startc = (char) -1;
  619.     }
  620.     ttyset(1);
  621.  
  622.     /* Go into cbreak, and -echo and -CRMOD */
  623.  
  624.     ignorf(signal(SIGHUP, finish));
  625.     ignorf(signal(SIGINT, finish));
  626.     ignorf(signal(SIGQUIT, SIG_IGN));
  627.     ignorf(signal(SIGBUS, finish));
  628.     ignorf(signal(SIGSEGV, finish));
  629.     ignorf(signal(SIGPIPE, finish));
  630.     ignorf(signal(SIGTERM, SIG_IGN));
  631.  
  632. }
  633.  
  634. ttyset(n)
  635. {
  636.     struct sgttyb    tty;
  637.  
  638.     if (ioctl(0, TIOCGETP, (char *) &tty) == -1) {
  639.         putstr("No terminal");
  640.         exit(1);
  641.     }
  642.     if (n) {
  643.         tty.sg_flags &= ~(ECHO | CRMOD);
  644.         tty.sg_flags |= (RAW);
  645.     } else {
  646.         tty.sg_flags |= (ECHO | CRMOD);
  647.         tty.sg_flags &= ~(RAW);
  648.     }
  649.     if (ioctl(0, TIOCSETN, (char *) &tty) == -1) {
  650.         putstr("cbreak?");
  651.         exit(1);
  652.     }
  653.     ioctl(0, TIOCSETC, n == 0 ? (char *) &tc1 : (char *) &tc2);
  654. #ifdef TIOCSLTC
  655.     ioctl(0, TIOCSLTC, n == 0 ? (char *) &ls1 : (char *) &ls2);
  656. #endif
  657. }
  658.  
  659.  
  660. #ifndef PROFILE
  661. exit(status)
  662. {
  663.  
  664.     flusho();
  665.     _exit(status);
  666. }
  667. #endif
  668.  
  669.  
  670. /* clone */
  671.  
  672. #else
  673.  
  674. charp()
  675. {
  676.     int c;
  677.  
  678.     if (Input)
  679.         return 0;
  680.     if (nchars)        /* Quick check */
  681.         return 1;
  682.  
  683.     else {
  684.         if(rawchkc())
  685.         return(1);
  686.         else return(0);
  687.     }
  688. }
  689.  
  690. /* null routine for testing. replace with exec call */
  691.  
  692. Suspend()
  693. {
  694. }
  695.  
  696. ttinit()
  697. {
  698. }
  699.  
  700. ttyset(n)
  701. int n;
  702. {
  703. }
  704.  
  705. conread(file,buf,size)
  706. unsigned char *buf;
  707. {
  708.     int p;
  709.     do {
  710.         p = rawgetc();
  711.         if(p == 0x0300) p = 3;
  712.         else p &= 0x7f;
  713.     } while (p == 0);
  714.     *buf++ = p;
  715.     return(1);
  716. }
  717. #endif
  718.  
  719. /* end */
  720.  
  721.